/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦，本文采用Apache-2.0许可证]
 * 
 * https://zhiqim.org/project/zhiqim_products/zhiqim_lucener.htm
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.zhiqim.lucener;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryparser.classic.ParseException;
import org.zhiqim.httpd.HttpRequest;
import org.zhiqim.kernel.Global;
import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.extend.HashMapSO;
import org.zhiqim.kernel.extend.MapSO;
import org.zhiqim.kernel.extend.MapSS;
import org.zhiqim.kernel.json.Jsons;
import org.zhiqim.kernel.paging.PageResult;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Lists;
import org.zhiqim.kernel.util.Validates;

@AnAlias("LucenePresenter")
public class LucenePresenter implements SignConstants
{
    /**
     * 查询索引是否存在
     * @param request
     * @throws IOException
     */
    public static void item(HttpRequest request) throws IOException
    {
        String id = request.getParameter(_ID_);
        Document doc = Global.getService(LuceneServer.class).item(id);
        
        MapSO map = new HashMapSO();
        map.put("id", doc==null?"":id);
        request.setResponseResult(Jsons.toString(map));
    }
    
    /**
     * 增加指定的索引，会检查id是否存在，存在则报错
     * 
     * @param request           请求，必须要求一个字段
     *                           1、id           编号，如果未传入则调用buildId
     *                           2、各字段表，如：
     *                              title        标题，必须，则不能为空
     *                              content      内容，非必须，可以为空，为空则不加入到索引字段中
     * @throws IOException      IO异常
     */
    public static void insert(HttpRequest request) throws IOException
    {
        Global.getService(LuceneServer.class).insert(request.getParameterMapOnCNT());
    }
    
    /**
     * 修改指定的索引
     * 
     * @param request           请求，必须要求一个字段
     *                           1、id           编号，必填
     *                           2、各字段表，如：
     *                              title        标题，必须的值=null表示不修改，为空，则报错
     *                              content      内容，非必须值=null表示不修改，为空，表示置空
     * @throws IOException      IO异常
     */
    public static void update(HttpRequest request) throws IOException
    {
        Global.getService(LuceneServer.class).update(request.getParameterMapOnCNT());
    }

    /**
     * 添加或修改指定的索引
     * 
     * @param request           请求，必须要求一个字段
     *                           1、id           编号，必填
     *                           2、各字段表，如：
     *                              title        标题，必须的值=null表示不修改，为空，则报错
     *                              content      内容，非必须值=null表示不修改，为空，表示置空
     * @throws IOException      IO异常
     */
    public static void updateOrInsert(HttpRequest request) throws IOException
    {
        MapSS map = request.getParameterMapOnCNT();
        String id = map.get(_ID_);
        Asserts.as(Validates.isNotEmptyBlank(id)?null:"修改数据时未传入[id]的值");
        
        //1.先查出文档
        Document doc = Global.getService(LuceneServer.class).item(id);
        if(doc == null)
            Global.getService(LuceneServer.class).insert(map);
        else
            Global.getService(LuceneServer.class).update(map);
    }
    
    /**
     * 删除指定的索引
     * 
     * @param request           请求，必须要求一个字段
     *                           1、id           编号
     * @throws IOException      IO异常
     */
    public static void delete(HttpRequest request) throws IOException
    {
        String id = request.getParameter(_ID_);
        Global.getService(LuceneServer.class).delete(id);
    }

    /**
     * 根据关键词和分页字段，获取查询的编号列表
     * 
     * @param request           请求，必须要求三个字段
     *                           1、page         页码
     *                           2、pageSize     页数
     *                           3、q            关键词
     *                           4、attr         属性词，可选
     * @throws IOException      IO异常
     * @throws ParseException   解析异常
     */
    public static void queryIds(HttpRequest request) throws IOException, ParseException
    {
        int page = request.getParameterInt("page", 1);
        int pageSize = request.getParameterInt("pageSize", 20);
        String q = request.getParameterNoFileterOnCNT("q");
        String field = request.getParameter("field", null);
        boolean reverse = request.getParameterBoolean("reverse");
        
        PageResult<Document> result = Global.getService(LuceneServer.class).page(page, pageSize, q, field, reverse);
        
        List<String> idList = new ArrayList<>();
        for (Document doc : result.list())
        {
            idList.add(doc.get(_ID_));
        }
        
        MapSO map = new HashMapSO();
        map.put("total", result.total());
        map.put("ids", Lists.toString(idList));
        request.setResponseResult(Jsons.toString(map));
    }
    
}
